
package com.ccExcelUtil.validator;

import com.ccExcelUtil.convertObject.ConvertObjectService;
import com.ccExcelUtil.service.ValidatedRelatedFieldService;
import com.ccExcelUtil.service.ValidatedRelatedSheetService;
import org.apache.commons.lang3.StringUtils;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.Validation;
import javax.validation.executable.ExecutableValidator;
import javax.validation.metadata.BeanDescriptor;
import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author xiaozhao
 */
public class ValidatorUtils {

    private static Validator validator;
    private static boolean initialized = false;

    public static final Map<String, ValidatedRelatedFieldService<Object>> VALIDATED_RELATED_FIELD_SERVICE_MAP = new ConcurrentHashMap<>();

    public static final Map<String, ValidatedRelatedSheetService<Object>> VALIDATED_RELATED_SHEET_SERVICE_MAP = new ConcurrentHashMap<>();

    public static final Map<String, ConvertObjectService<Object, Object>> CONVERT_OBJECT_SERVICE_MAP = new ConcurrentHashMap<>();

    /**
     * 校验对象
     *
     * @param object 待校验对象
     * @param groups 待校验的组
     */
    /**
     * 初始化校验器，必须在第一次使用前调用
     */
    public static void initialize() {
        if (!initialized) {
            try {
                // 使用 ParameterMessageInterpolator 避免对 javax.el 的依赖
                ValidatorFactory factory = Validation
                    .byDefaultProvider()
                    .configure()
                    .messageInterpolator(new ParameterMessageInterpolator())
                    .buildValidatorFactory();
                validator = factory.getValidator();
                initialized = true;
            } catch (Exception e) {
                // 如果Hibernate Validator初始化失败，尝试使用简单的实现
                System.err.println("警告: 无法初始化Hibernate Validator，使用简单校验模式: " + e.getMessage());
                validator = new SimpleValidator();
                initialized = true;
            }
        }
    }

    /**
     * 注册字段校验服务
     *
     * @param service 字段校验服务实现
     */
    public static void registerFieldService(ValidatedRelatedFieldService<?> service) {
        String typeName = getTypeName(service);
        VALIDATED_RELATED_FIELD_SERVICE_MAP.put(typeName, (ValidatedRelatedFieldService<Object>) service);
    }

    /**
     * 注册Sheet校验服务
     *
     * @param service Sheet校验服务实现
     */
    public static void registerSheetService(ValidatedRelatedSheetService<?> service) {
        String typeName = getTypeName(service);
        VALIDATED_RELATED_SHEET_SERVICE_MAP.put(typeName, (ValidatedRelatedSheetService<Object>) service);
    }

    /**
     * 注册对象转换服务
     *
     * @param service 对象转换服务实现
     */
    public static void registerConvertService(ConvertObjectService<?, ?> service) {
        String typeName = getTypeName(service);
        CONVERT_OBJECT_SERVICE_MAP.put(typeName, (ConvertObjectService<Object, Object>) service);
    }

    public static Set<ConstraintViolation<Object>> validateEntity(Object object, Class<?>... groups) {
        if (!initialized) {
            initialize();
        }
        return validator.validate(object, groups);
    }

    public static Map<String, Object> getValidatedObject(Object o, Class<?>... groups) {
        Set<ConstraintViolation<Object>> constraintViolations = validateEntity(o, groups);
        Map<String, Object> map = new HashMap<>();
        constraintViolations.forEach(item -> {
            String message = item.getMessage();
            String filedName = item.getPropertyPath().toString();
            if (StringUtils.isNotBlank(filedName)) {
                map.put(filedName, message);
            }
        });
        return map;
    }

    private static String getTypeName(Object o) {
        Type[] genericInterfaces = o.getClass().getGenericInterfaces();
        ParameterizedType genericInterface = (ParameterizedType) genericInterfaces[0];
        Type[] actualTypeArguments = genericInterface.getActualTypeArguments();
        return actualTypeArguments[0].getTypeName();
    }

    /**
     * 简单的Validator实现，用于在Hibernate Validator不可用时提供基本功能
     */
    private static class SimpleValidator implements Validator {
        @Override
        public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) {
            // 简单实现：返回空集合，表示没有校验错误
            return new java.util.HashSet<>();
        }

        @Override
        public <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>... groups) {
            return new java.util.HashSet<>();
        }

        @Override
        public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) {
            return new java.util.HashSet<>();
        }

        @Override
        public BeanDescriptor getConstraintsForClass(Class<?> clazz) {
            return null;
        }

        @Override
        public <T> T unwrap(Class<T> type) {
            return null;
        }

        @Override
        public ExecutableValidator forExecutables() {
            return null;
        }
    }
}